package com.zhuiyun.project.api.system.menu.controller;

import com.zhuiyun.project.annotation.OptLog;
import com.zhuiyun.project.api.system.menu.entity.SysMenu;
import com.zhuiyun.project.api.system.menu.model.SysMenuModel;
import com.zhuiyun.project.api.system.menu.service.SysMenuService;
import com.zhuiyun.project.common.constant.UserConstants;
import com.zhuiyun.project.common.controller.BaseController;
import com.zhuiyun.project.common.errorCode.CommonException;
import com.zhuiyun.project.common.errorCode.EmErrorCode;
import com.zhuiyun.project.common.response.CommonResult;
import com.zhuiyun.project.utils.BeanUtils;
import com.zhuiyun.project.utils.StringUtils;
import com.zhuiyun.project.utils.constants.CommonConstants;
import com.zhuiyun.project.utils.validator.ValidatorUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;


import java.util.HashMap;
import java.util.List;

/**
 * 菜单权限Controller
 * 
 * @author ruoyi
 * @date 2023-06-16
 */
@RestController
@Api(tags = "菜单管理")
@Slf4j
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController {

    @Autowired
    private SysMenuService sysMenuService;

    /**
    * @Description 查询菜单权限列表
    * @Author lzy
    * @Date 2023/6/20 11:15
    * @Return com.zhuiyun.project.common.response.CommonResult
    * @param sysMenu
    */
    @PreAuthorize("@ss.hasPermi('system:menu:list')")
    @ApiOperation(value = "菜单管理的全查方法")
    @OptLog(modular = "菜单管理", type = CommonConstants.SELECT, describe = "查询菜单")
    @GetMapping("/list")
    public CommonResult list(SysMenu sysMenu) {
        log.info("查询菜单信息列表");
        return sysMenuService.selectSysMenuList(sysMenu);
    }

    /**
    * @Description 获取菜单权限详细信息
    * @Author lzy
    * @Date 2023/6/20 11:14
    * @Return com.zhuiyun.project.common.response.CommonResult
    * @param menuId
    */
    @PreAuthorize("@ss.hasPermi('system:menu:query')")
    @ApiOperation(value = "菜单管理的详细信息查询方法")
    @OptLog(modular = "菜单管理", type = CommonConstants.SELECT, describe = "菜单详细信息查询")
    @GetMapping(value = "/{menuId}")
    public CommonResult getInfo(@PathVariable("menuId") Long menuId) {
        log.info("菜单详细信息查询");
        return CommonResult.ok(sysMenuService.selectSysMenuByMenuId(menuId));
    }

    /**
    * @Description 新增菜单权限
    * @Author lzy
    * @Date 2023/6/20 11:14
    * @Return com.zhuiyun.project.common.response.CommonResult
    * @param sysMenuModel
    */
    @PreAuthorize("@ss.hasPermi('system:menu:add')")
    @ApiOperation(value = "菜单管理的添加方法")
    @OptLog(modular = "菜单管理", type = CommonConstants.ADD, describe = "添加菜单")
    @PostMapping
    public CommonResult add(@RequestBody SysMenuModel sysMenuModel) throws CommonException {
        log.info("添加菜单");
        if(ValidatorUtil.ValidationObject(sysMenuModel)) {
            SysMenu sysMenu = new SysMenu();
            BeanUtils.copy(sysMenuModel, sysMenu);
            if (!sysMenuService.checkMenuNameUnique(sysMenu))
            {
                return CommonResult.error("新增菜单'" + sysMenuModel.getMenuName() + "'失败，菜单名称已存在");
            }
            else if (UserConstants.YES_FRAME.equals(sysMenuModel.getIsFrame()) && !StringUtils.ishttp(sysMenu.getPath()))
            {
                return CommonResult.error("新增菜单'" + sysMenuModel.getMenuName() + "'失败，地址必须以http(s)://开头");
            }
            sysMenu.setCreateBy(getLoginName());
            return sysMenuService.insertSysMenu(sysMenu);
        } else {
            return CommonResult.ok(EmErrorCode.SAVE_ERROR);
        }
    }

    /**
    * @Description 修改菜单权限
    * @Author lzy
    * @Date 2023/6/20 11:14
    * @Return com.zhuiyun.project.common.response.CommonResult
    * @param sysMenuModel
    */
    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
    @ApiOperation(value = "菜单管理的修改方法")
    @OptLog(modular = "菜单管理", type = CommonConstants.UPDATE, describe = "修改菜单")
    @PutMapping
    public CommonResult edit(@RequestBody SysMenuModel sysMenuModel) throws CommonException {
        log.info("修改菜单");
        if(ValidatorUtil.ValidationObject(sysMenuModel)) {
            SysMenu sysMenu = new SysMenu();
            BeanUtils.copy(sysMenuModel, sysMenu);
            if (!sysMenuService.checkMenuNameUnique(sysMenu))
            {
                return CommonResult.error("修改菜单'" + sysMenu.getMenuName() + "'失败，菜单名称已存在");
            }
            else if (UserConstants.YES_FRAME.equals(sysMenu.getIsFrame()) && !StringUtils.ishttp(sysMenu.getPath()))
            {
                return CommonResult.error("修改菜单'" + sysMenu.getMenuName() + "'失败，地址必须以http(s)://开头");
            }
            else if (sysMenu.getMenuId().equals(sysMenu.getParentId()))
            {
                return CommonResult.error("修改菜单'" + sysMenu.getMenuName() + "'失败，上级菜单不能选择自己");
            }
            return sysMenuService.updateSysMenu(sysMenu);
        } else {
            return CommonResult.error(EmErrorCode.UPDATE_ERROR);
        }
    }

    /**
    * @Description 删除菜单权限
    * @Author lzy
    * @Date 2023/6/20 11:14
    * @Return com.zhuiyun.project.common.response.CommonResult
    * @param menuIds
    */
    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
    @ApiOperation(value = "菜单管理的删除方法")
    @OptLog(modular = "菜单管理", type = CommonConstants.DELETE, describe = "删除菜单")
	@DeleteMapping("/{menuIds}")
    public CommonResult remove(@PathVariable Long[] menuIds) {
        log.info("删除菜单");
        return sysMenuService.deleteSysMenuByMenuIds(menuIds);
    }

    /**
     * 导出菜单权限列表
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:export')")
//    @PostMapping("/export")
//    public void export(HttpServletResponse response, SysMenu sysMenu) {
//        List<SysMenu> list = sysMenuService.selectSysMenuList(sysMenu);
//        ExcelUtil<SysMenu> util = new ExcelUtil<SysMenu>(SysMenu.class);
//        util.exportExcel(response, list, "菜单权限数据");
//    }

    /**
    * @Author hbx
    * @Description 获取菜单下拉树列表
    * @Date 2023/6/22 9:20
    * @param menu
    */
    @ApiOperation(value = "菜单下拉树查询")
    @OptLog(modular = "角色管理", type = CommonConstants.SELECT, describe = "菜单拉下数查询")
    @GetMapping("/treeselect")
    public CommonResult treeselect(SysMenu menu)
    {
        List<SysMenu> menus = sysMenuService.selectMenuList(menu, getUserId());
        return CommonResult.ok(sysMenuService.buildMenuTreeSelect(menus));
    }

    /**
     * 加载对应角色菜单列表树
     */
    @ApiOperation(value = "根据角色id查询菜单树")
    @OptLog(modular = "角色管理" , type = CommonConstants.SELECT , describe = "根据角色id查询菜单树")
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public CommonResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
        List<SysMenu> menus = sysMenuService.selectMenuList(getUserId());
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("checkedKeys", sysMenuService.selectMenuListByRoleId(roleId));
        hashMap.put("menus", sysMenuService.buildMenuTreeSelect(menus));
        return CommonResult.ok(hashMap);
    }
}
